<?php

/**
* Clase para almacenar datos de una Oferta
*
* @access public
* @author Yandi Naranjo 
*/
class Offer {

  private $id;
  private $title;
  private $highlighted;
  
  /**
  * constructor de clase
  *
  *Inicializa las variables de la instancia
  *   
  * @access public
  */
  public function __construct () {
    
    $this->id           = 0;
    $this->title        = "";
    $this->highlighted  = 0;
    
  }
  
  /**
  * Devuelve el id de la oferta
  *   
  * @access public
  * @return Id de la oferta 
  */
  public function getId () {
    
    return $this->id;
    
  } 
  
  /**
  * Devuelve el titulo de la oferta
  *   
  * @access public
  * @return Titulo de la oferta 
  */
  public function getTitle () {
    
    return $this->title;
    
  } 
  
  /**
  * Devuelve el color a usar en la oferta
  *   
  * @access public
  * @return Color a usar en oferta 
  */
  public function getHighlighted () {
    
    return $this->highlighted;
    
  } 
  
  /**
  * Cambia el valor de id de la oferta
  *   
  * @access public
  * @param Nuevo valor de id de la oferta 
  */
  public function setId ($id) {
    
    $this->id = $id;
    
  } 
  
  /**
  * Cambia el valor de titulo de la oferta
  *   
  * @access public
  * @param Nuevo valor de titulo de la oferta 
  */
  public function setTitle ($title) {
    
    $this->title = $title;
    
  } 
  
  /**
  * Cambia el valor del color a usarn en la oferta
  *   
  * @access public
  * @param Nuevo valor del color a usarn en la oferta 
  */
  public function setHighlighted ($highlighted) {
    
    $this->highlighted = $highlighted;
    
  } 
  
  /**
  * Cambia el valor de un campo de la oferta dado el nombre
  *   
  * @access public
  * @param Nombre del campo a cambiar
  * @param Nuevo valor 
  */
  public function set ($field, $value) {
    
    if      (!strcmp($field, "id"))          $this->setId ($value);
    else if (!strcmp($field, "title"))       $this->setTitle ($value);
    else if (!strcmp($field, "highlighted")) $this->setHighlighted ($value);
    
  }

  /**
  * Borra toda la información en la oferta
  *   
  * @access public
  */
  public function clearData () {
    
    $this->id           = 0;
    $this->title        = "";
    $this->highlighted  = 0;
    
  }
  
}

/**
* Clase para manejar la información referente a las Ofertas en un fichero XML
*
* @access public
* @author Yandi Naranjo 
*/
class HandleXMLOffers {
  
  const   offerFile = "xml/offers.xml";

  private $file;
  private $xmlObj;
  private $xmlIterator;
  private $currentOffer;
  
  private $random;
  private $randomPos;

  /**
  * Constructor de la clase
  *   
  * Carga los datos del fichero XML entrado o el usado por defecto en memoria
  * Se emplea un objeto SimpleXMLElement para almacenar los datos (Inicializado con los datos del fichero XML)
  * Se emplea un objeto SimpleXMLIterator para procesar las peticiones (Inicializado con el objeto SimpleXMLElement)
  * Se emplea un objeto Offer para proveer los datos de cada oferta (Inicializado con valores por defecto)    
  * 
  * @access public
  * @param Nombre del fichero XML
  */
  public function __construct($namefile) {

    $this->file         = (empty($namefile) || $namefile == NULL)?(HandleXMLOffers::offerFile):$namefile;   
    $this->xmlObj       = new SimpleXMLElement($this->file, NULL, TRUE);
    $this->xmlIterator  = new SimpleXMLIterator($this->xmlObj->asXML());
    $this->currentOffer = new Offer ();
    
    $this->randomPos = 0;
    $this->random    = range(1, $this->xmlObj->count());
    
  }
  
  /**
  * Devuelve el nombre del fichero XML empleado
  *   
  * @access public
  * @return Nombre Fichero XML 
  */
  public function getFile () {
    
    return $this->file;
    
  }
  
  /**
  * Devuelve el objeto SimpleXMLElement
  *   
  * @access public
  * @return Objeto SimpleXMLElement 
  */
  public function getXmlObj () {
    
    return $this->xmlObj;
    
  }
  
  /**
  * Devuelve el Iterador de SimpleXMLElement
  *   
  * @access public
  * @return Objeto SimpleXMLIterator 
  */
  public function getXmlIterator () {
    
    return $this->xmlIterator;
    
  }
  
  /**
  * Devuelve la oferta actual
  *   
  * @access public
  * @return Objeto Offer 
  */
  public function getCurrentOffer () {
    
    return $this->currentOffer;
    
  }
  
  /**
  * Inicializa el Iterador SimpleXMLIterator
  *   
  * @access public
  */
  public function rewinOffers () {
    
    $this->xmlIterator->rewind();
    
  }
  
  /**
  * Devuelve la siguiente oferta proporcionada por el iterador SimpleXMLIterator
  *   
  * @access public
  * @return Objeto Offer
  */
  public function nextOffer () {
    
    $this->currentOffer->clearData();
    
    if ($this->xmlIterator->valid()) {
      
      foreach($this->xmlIterator->getChildren() as $name => $data) {
        if      (!strcmp($name, "id"))        $this->currentOffer->setId($data);
        else if (!strcmp($name, "title"))     $this->currentOffer->setTitle($data);
        else if (!strcmp($name, "highlight")) $this->currentOffer->setHighlighted($data);
      }

      $this->xmlIterator->next();

    }
    
  }
  
  /**
  * Adiciona un nueva oferta y actualiza el fichero XML
  *   
  * @access public
  * @param Titulo de la Oferta
  * @param Si está resaltado o no [Normal, Amarillo]
  */
  public function addOffer ($title, $highlighted) {

    $maxId = 0;
    
    for ($this->xmlIterator->rewind(); $this->xmlIterator->valid(); $this->xmlIterator->next())
      foreach ($this->xmlIterator->getChildren() as $name => $data) 
        if (!strcmp($name, "id") && intval($data) > intval($maxId)) 
          $maxId = $data;

    $maxId = intval($maxId) + 1;   
        
    $offer = $this->xmlObj->addChild("offer");
    
    $offer->addChild("id", $maxId);
    $offer->addChild("title", $title);
    $offer->addChild("highlight", $highlighted);

    $this->xmlObj->saveXML($this->file);
    
    return $maxId;
    
  }
  
  /**
  * Actualiza una oferta y actualiza el fichero XML
  *   
  * @access public
  * @param Id de la Oferta a modificar
  * @param Nombre de campo a modificar en la Oferta
  * @param Nuevo valor del campo de la Oferta 
  */
  public function updateOffer ($id, $column, $value) {
    
    foreach ($this->xmlObj as $offer)
      if ($offer->id == $id) {
        if ($column == "Ofertas") $offer->title     = $value;
        if ($column == "Estilo")  $offer->highlight = $value;
      }
    
    $this->xmlObj->saveXML($this->file);
    
  }
  
  /**
  * Borra una oferta y actualiza el fichero XML
  *   
  * @access public
  * @param Id de la Oferta a borrar
  */
  public function deleteOffer ($id) {
    
    foreach ($this->xmlObj as $offer)
      if ($offer->id == $id) {
        $dom = dom_import_simplexml($offer);
        $dom->parentNode->removeChild($dom);
      }
    
    $this->xmlObj->saveXML($this->file);
    
  }
  
  /**
  * Crea un arreglo y realiza un shuffle para usar los valores ordenados como random
  *   
  * @access public
  */
  public function shuffle () {
    
    $this->randomPos = 0;
    $this->random    = range(1, $this->xmlObj->count());
    shuffle($this->random);
    
  }
  
  /**
  * Devuelve la siguiente oferta random
  *   
  * @access public
  * @return Objeto Offer
  */
  public function nextRandom () {
    
    $this->currentOffer->clearData();
    
    $counter = 1;
    $cond    = false;
    
    if ($this->randomPos++ > $this->xmlObj->count())
      $this->shuffle ();
    
    for ($this->xmlIterator->rewind(); $this->xmlIterator->valid() && !$cond; $this->xmlIterator->next())
      if ($counter++ == $this->random[$this->randomPos]) {
        
        $cond = true;
        
        foreach($this->xmlIterator->getChildren() as $name => $data) {
          if      (!strcmp($name, "id"))        $this->currentOffer->setId($data);
          else if (!strcmp($name, "title"))     $this->currentOffer->setTitle($data);
          else if (!strcmp($name, "highlight")) $this->currentOffer->setHighlighted($data);
        }
        
      }
      
    return $this->currentOffer;  
    
  }
  
  /**
  * Devuelve la numero de ofertas con un estilo (Normal, Amarillo)
  *   
  * @access public
  * @return Cantidad de ofertas en el XML con el estilo dado
  */
  public function numberOffer ($style) {
    
    $counter = 0;
    
    for ($this->xmlIterator->rewind(); $this->xmlIterator->valid(); $this->xmlIterator->next())
      foreach($this->xmlIterator->getChildren() as $name => $data)
        if (!strcmp($name, "highlight") && !strcmp($data, $style)) 
          $counter++;
      
    return $counter;    
        
  }
  
}

?>
